home *** CD-ROM | disk | FTP | other *** search
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #ifdef HAS_SYSLOG
- #include <syslog.h>
- #endif
- #include "getopt.h"
- #include "lutil.h"
- #include "xutil.h"
- #include "ftn.h"
- #include "config.h"
- #include "scanout.h"
- #include "version.h"
-
- extern int f_lock(char *);
- extern void funlock(int);
- extern int nodelock(faddr *);
- extern int nodeulock(faddr *);
- extern int execute(char *,char *,char *,char *,char *,char *);
- extern long sequencer(void);
- extern char *arcname(faddr *,char);
- extern char *floname(faddr *,char);
- extern char *splname(faddr *,char);
-
- extern char *logname;
-
- static int each(faddr*,char,int,char*);
- static int packets_ok=0,packets=0;
- static char *dow[] = {"su","mo","tu","we","th","fr","sa"};
- static char *ext;
-
- void usage(name)
- char *name;
- {
- confusage("");
- }
-
- int main(argc,argv)
- int argc;
- char *argv[];
- {
- int c,rc;
- time_t tt;
- struct tm *ptm;
-
- #ifdef MAILLOG
- logfacility=MAILLOG;
- #endif
-
- setmyname(argv[0]);
- while ((c=getopt(argc,argv,"x:l:h")) != -1)
- if (confopt(c,optarg)) switch (c)
- {
- default: usage(); exit(1);
- }
-
- umask(066);
-
- if ((rc=readconfig()))
- {
- logerr("Error getting configuration, aborting\n");
- return rc;
- }
-
- (void)time(&tt);
- ptm=localtime(&tt);
- ext=dow[ptm->tm_wday];
- debug(3,"today's arcmail extention \"%s\"",ext);
-
- if ((rc=scanout(each)))
- {
- logerr("Error scanning outbound, aborting\n");
- return rc;
- }
-
- if (packets) loginf("processed %d of %d packets, rc=%d",
- packets_ok,packets,rc);
- return 0;
- }
-
- static int each(addr,flavor,isflo,pktfn)
- faddr *addr;
- char flavor;
- int isflo;
- char *pktfn;
- {
- int rc=0;
- int absent,needadd;
- int pl;
- char *flofn,*arcfn,*splfn;
- char c,*p;
- char packet[13];
- char pkt[13];
- char buf[512];
- FILE *fp;
- struct flock fl;
- struct stat stbuf;
-
- if (isflo == OUT_FLO) return 0; /* we don't want flo files */
-
- if (isflo == OUT_ARC) /* remove empty non-today files */
- {
- if (strncasecmp(pktfn+strlen(pktfn)-3,ext,2) == 0) return 0;
- if ((stat(pktfn,&stbuf) == 0) && (stbuf.st_size == 0))
- {
- debug(3,"unlink non-todays empty arcmail \"%s\"",
- pktfn);
- unlink(pktfn);
- }
- return 0;
- }
-
- if (nodelock(addr))
- {
- debug(3,"system %s locked, skipping",ascfnode(addr,0x1f));
- return 0;
- }
-
- debug(3,"packing '%c'-flavor packet \"%s\" to node %s",
- flavor,pktfn,ascfnode(addr,0x1f));
- packets++;
-
- if ((p=strrchr(pktfn,'/')))
- {
- *p='\0';
- if (chdir(pktfn) != 0)
- {
- logerr("$cannot chdir(\"%s\")",pktfn);
- nodeulock(addr);
- return 1;
- }
- strncpy(packet,p+1,12);
- packet[12]='\0';
- *p='/';
- }
- else
- {
- logerr("cannot be: packet name \"%s\" without slash",pktfn);
- nodeulock(addr);
- return 1;
- }
- if ((pl=f_lock(pktfn)) == -1)
- {
- debug(3,"cannot lock packet \"%s\", skipping",pktfn);
- nodeulock(addr);
- return 0;
- }
- arcfn=xstrcpy(arcname(addr,flavor));
- flofn=xstrcpy(floname(addr,flavor));
- splfn=xstrcpy(splname(addr,flavor));
-
- if ((fp=fopen(flofn,"r+")) == NULL)
- if ((fp=fopen(flofn,"w")) == NULL)
- {
- logerr("$could not open flo file \"%s\"",flofn);
- rc=1;
- goto leave;
- }
- fl.l_type=F_WRLCK;
- fl.l_whence=0;
- fl.l_start=0L;
- fl.l_len=0L;
- if (fcntl(fileno(fp),F_SETLK,&fl) < 0)
- {
- if (errno != EAGAIN)
- logerr("$Unable to lock flo file \"%s\"",flofn);
- else
- debug(3,"skipping locked flo file \"%s\"",flofn);
- fclose(fp);
- goto leave;
- }
- if (stat(flofn,&stbuf) != 0)
- {
- debug(3,"$Unable to access flo file \"%s\"",flofn);
- fclose(fp);
- goto leave;
- }
-
- p=arcfn+strlen(arcfn)-1;
- absent=1;
- while (fgets(buf,sizeof(buf)-1,fp))
- {
- if (strncmp(buf+1,arcfn,strlen(arcfn)-1) == 0)
- {
- absent=0;
- c=buf[strlen(arcfn)];
- if (*p < c) *p=c;
- debug(3,"arc file mentioned in flo, new name \"%s\"",
- arcfn);
- }
- }
-
- needadd=0;
- if (absent)
- {
- debug(3,"no arcmail file mentioned in flo file, create new");
- needadd=1;
- while (stat(arcfn,&stbuf) == 0)
- if (*p == '9') *p='a'; else (*p)++;
- }
- else if (((stat(arcfn,&stbuf) == 0) && (((stbuf.st_size == 0L) ||
- ((maxfsize > 0) && (stbuf.st_size > maxfsize))))) ||
- (stat(splfn,&stbuf) != -1))
- {
- debug(3,"arc file mentioned in flo file, but new requested");
- needadd=1;
- unlink(splfn);
- do
- {
- if (*p == '9') *p='a'; else (*p)++;
- }
- while (stat(arcfn,&stbuf) == 0);
- }
-
- sprintf(pkt,"%08lx.pkt",sequencer());
-
- if (rename(packet,pkt) < 0)
- {
- logerr("$cannot rename \"%s\" to \"%s\"",packet,pkt);
- fclose(fp);
- goto leave;
- }
-
- debug(3,"using .flo file \"%s\", arc file \"%s\", packet \"%s\" -> \"%s\"",
- flofn,arcfn,pktfn,pkt);
- rc=execute(packer,arcfn,pkt,"/dev/null",logname,logname);
- if (rc == 0)
- {
- unlink(pkt);
- if (needadd)
- {
- fprintf(fp,"#%s\n",arcfn);
- }
- }
- else rename(pkt,packet);
- fclose(fp);
-
- leave:
- free(arcfn);
- free(flofn);
- free(splfn);
- funlock(pl);
- nodeulock(addr);
- if (rc == 0) packets_ok++;
- return rc;
- }
-